/* ====================================================================
 * 作者-------  支叶
 * 创作时间---  20220403
 * 功能-------  第三方接口示例（ThirdLib.c 定义应用程序的导出函数）
 * 运行环境---  长沙思知所提供的自然语运行环境
 * 修改时间---  20251001（调整命名规则）
 */
//====================================================================
#include "ThirdBasics.h"
#include "sz_api_ext.h"

//=======dll init=======================
void sz_lib_attach(void* p) { //这里LOG还未完成初始化，不能用LOG输出
	printf("Thirdlib Init...\n"); 
}

//=======dll deinit===========================
void sz_lib_detach(void *p) {
	printf("...Thirdlib DeInit");
}

//=============函数接口区============================
int exp_func1(EnvP evn, ExpUnit*& in_out)
{
	//输入参数都是按顺序链接,下一个参数必须有前一个参数存在。
	ExpUnit *pOne = sz_parsing_unit(in_out);
	if(pOne != NULL) {
		LG("pOne->type=%d",pOne->type);
		ExpUnit *pTwo = sz_parsing_unit(in_out->pNext);
		if(pTwo != NULL) {
			LG("pTwo->type=%d",pTwo->type);
			ExpUnit *pThree = sz_parsing_unit(in_out->pNext->pNext);
			if(pThree != NULL) {
				LG("pThree->type=%d",pThree->type);
				//..........
			}
		}
	}
	//---------执行模块--------------------
	//...
	//--------填充结果返回------------------------
	sz_set_unit_bool(in_out,true);  //返回的第一个参数
	sz_set_unit_int(in_out->pNext,100); //返回的第二个参数
	sz_set_unit_num(in_out->pNext->pNext,200); //返回的第三个参数
	sz_take_unit_dbs(in_out->pNext->pNext->pNext, DATA_STR, sz_get_dbs("test OK",7)); //返回的第四个参数
	return 4;	//返回4个参数
}

int exp_func2(EnvP evn, ExpUnit*& in_out) //(a,b,c) -> (a+b)*c ->
{
	ExpUnit* pA = sz_parsing_unit(in_out);
	if (pA == NULL || pA->type != TYPE_NUM) return -5; //第一个参数必须是数值，返回-5 输入参数不满足函数运行。
	ExpUnit* pB = sz_parsing_unit(in_out->pNext);
	if (pB == NULL || pB->type != TYPE_NUM) return -5; //第二个参数必须是数值，返回-5 输入参数不满足函数运行。
	ExpUnit* pC = sz_parsing_unit(in_out->pNext->pNext);
	if (pC == NULL || pC->type != TYPE_NUM) return -5; //第三个参数必须是数值，返回-5 输入参数不满足函数运行。
	intptr_t a, b, c;
	a = SZ_GET_INT_VALUE(pA); //无论 pA 是浮点还是整型，都转成整型赋值给 a 。
	b = SZ_GET_INT_VALUE(pB); //同上
	c = SZ_GET_INT_VALUE(pC); //同上
	//--------填充结果返回------------------------
	sz_set_unit_int(in_out, (a + b) * c); //返回的第一个参数
	return 1;	//返回1个参数
}

int exp_func3(EnvP evn, ExpUnit*& in_out)
{
	ExpUnit *pPar = sz_parsing_unit(in_out);
	if (pPar == NULL || pPar->type != TYPE_DATA) return -5; //第一个参数必须是data 型，返回-5 输入参数不满足函数运行。
	//---------执行模块--------------------
	LG("FunTest2[%d]:%s",pPar->pBfS->Len,pPar->pBfS->pStr);
	//--------显示所有属性---------------
	DataBufStr *dbs = sz_get_dbs(NULL,pPar->pBfS->Len+4); //早请Len+4的空间
	memcpy(dbs->pStr,pPar->pBfS->pStr, pPar->pBfS->Len);
	strcpy(dbs->pStr+pPar->pBfS->Len,"+dgz");
	//--------填充结果返回------------------------
	sz_take_unit_dbs(in_out, DATA_STR, dbs); //返回的第一个参数,dbs 已经嵌入in_out中，不需要再释放
	return 1;	//返回1个参数
}

int exp_square(EnvP env, ExpUnit* &in_out)
{
	ExpUnit *pPar = sz_parsing_unit(in_out);
	//---------执行模块--------------------
	if (pPar->type == TYPE_NUM) {
		if(pPar->tval == NUM_NUM)
			in_out->iNum = pPar->iNum * pPar->iNum;
		else
			in_out->iVal = pPar->iVal * pPar->iVal;
	}
	else return 0;
	in_out->space = SPACE_NULL; //消除指针类型
	in_out->type = pPar->type;
	return 1;
}

int exp_read_file(EnvP evn, ExpUnit*& in_out) //(pathname) -> data
{
	ExpUnit *PathName = sz_parsing_unit(in_out);
	if (PathName == NULL || PathName->type != TYPE_DATA) return -5; //第一个参数必须是data 型
	//---------执行模块--------------------
	LG("sz_read_file[%d]:%s",PathName->pBfS->Len,PathName->pBfS->pStr);
	DataBufStr *dbs = sz_read_file(PathName->pBfS->pStr);
	//--------填充结果返回------------------------
	sz_take_unit_dbs(in_out, DATA_BUF, dbs); //返回的第一个参数,dbs 已经嵌入in_out中，不需要再释放(当 dbs为null时，内部转为 FALSE )
	return 1;	//返回1个参数
}

//=====================配置==================================================
//=========函数对应表(名称,功能，使用规则，最后以NULL结束)=================
static const SzFuncTable funs_normal_tbl =
{
	FUNC_TYPE_I,	1,
	(1 << 16) | (1 << 8) | (10), //ver:1.1.10
	"test", //ArrayName is "test",Add "test." when accessing 
	{
		"fun1",		exp_func1,
		"fun2",		exp_func2,
		"fun3",		exp_func3,
		"square",	exp_square,
		"readfile",	exp_read_file,
		NULL,		NULL,	//结束行
	}
};
//注：调用方式为：test.fun1(参数1,参数2,参数3,...),当ArrayName为NULL时，表示不需要表名，直接调用函数名即可。

/*
开发者信息(JSON格式{id:var,id2:var2,....})说明：
ID 	：已注册的开发者编号（版权依据，贡献依据，收益凭证），没有可以无此项
公司	：个人开发者不需要填此项
作者	：开发者姓名
手机	：开发者手机号（当无开发者编号时，也可以作为贡献版权依据）
*/
const char sDeveloperInfo[] = \
"{\"ID\":\"00000001-0001-0001\","\
"\"公司\":\"长沙思知\","        \
"\"电话\":\"0731****8888\","     \
"\"作者\":\"支叶\","             \
"\"手机\":\"138****8888\"}";

//const char sDeveloperCert[]

//==============导出总接口：gTotalInterSet==================
extern const SzImportSystem gTotalInterSet =
{
	sDeveloperInfo,
	NULL, //开发者证书
	{
		&funs_normal_tbl,
		NULL,	//结束行
	}
};




